1
|
|
|
import React, { Component } from "react"; |
2
|
|
|
import "../scss/components/Toast.scss"; |
3
|
|
|
|
4
|
|
|
class Toast extends Component { |
5
|
|
|
state = { |
6
|
|
|
visible: false, |
7
|
|
|
type: "primary", |
8
|
|
|
message: "", |
9
|
|
|
transitionDirection: "right", |
10
|
|
|
position: "top-right", |
11
|
|
|
timeout: 5000 |
12
|
|
|
} |
13
|
|
|
toastTimeout = null; |
14
|
|
|
throwToast = (message, type, options) => { |
15
|
|
|
const { transitionDirection, position, timeout } = options; |
16
|
|
|
const validPositions = ["top-right", "top-left", "top-center", "bottom-right", "bottom-left", "bottom-center"]; |
17
|
|
|
const validTypes = ["warn", "success", "error", "info", "primary"]; |
18
|
|
|
this.setState({ message, type: [...validTypes].includes(type) ? type : "primary", transitionDirection, position: [...validPositions].includes(position) ? position || "top-right" : "top-right", timeout: timeout || 5000 }, () => { |
19
|
|
|
setTimeout(() => { |
20
|
|
|
this.setState({ visible: true }, () => { |
21
|
|
|
this.toastTimeout = setTimeout(() => { |
22
|
|
|
if (this.state.visible) { |
23
|
|
|
this.setState({ visible: false }); |
24
|
|
|
} |
25
|
|
|
}, this.state.timeout); |
26
|
|
|
}); |
27
|
|
|
}, 250); |
28
|
|
|
}); |
29
|
|
|
} |
30
|
|
|
toast = (message, type, options = {}) => { |
31
|
|
|
if (this.state.visible) { |
32
|
|
|
clearTimeout(this.toastTimeout); |
33
|
|
|
this.setState({ visible: false }, () => { |
34
|
|
|
setTimeout(() => { |
35
|
|
|
this.throwToast(message, type, options); |
36
|
|
|
}, 250); |
37
|
|
|
}); |
38
|
|
|
} else { |
39
|
|
|
this.throwToast(message, type, options); |
40
|
|
|
} |
41
|
|
|
} |
42
|
|
|
closeToast = () => { |
43
|
|
|
clearTimeout(this.toastTimeout); |
44
|
|
|
this.setState({ visible: false }); |
45
|
|
|
} |
46
|
|
|
determineShiftDirection = (position, transitionDirection) => { |
47
|
|
|
const directions = position.split("-"); |
48
|
|
|
if (directions.includes("center")) { |
49
|
|
|
return directions[0]; |
50
|
|
|
} else { |
51
|
|
|
if (directions.includes(transitionDirection)) { |
52
|
|
|
return transitionDirection; |
53
|
|
|
} else { |
54
|
|
|
return directions[1]; |
55
|
|
|
} |
56
|
|
|
} |
57
|
|
|
} |
58
|
|
|
renderToast = (message, visible, type) => { |
59
|
|
|
const { transitionDirection, position } = this.state; |
60
|
|
|
const shiftDirection = this.determineShiftDirection(position, transitionDirection); |
61
|
|
|
return <div onClick={this.closeToast} className={`${"toast"} ${visible ? "show" : "hide"}-${shiftDirection} ${type} ${position}`}>{message}</div> |
62
|
|
|
} |
63
|
|
|
render() { |
64
|
|
|
const { message, visible, type } = this.state; |
65
|
|
|
return (<>{this.renderToast(message, visible, type)}</>); |
66
|
|
|
} |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
export default Toast; |